#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>

int cnt = 1000;

// 初始化条件变量。
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;

// 初始化互斥锁。
pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

void* Name(void* argv)
{
    std::string name = static_cast<char*>(argv);
    while(true)
    {
        // cond：要在这个条件上等待，相当于main线程给新线程信号。
        // 给互斥锁锁上各个线程，等待main线程或是其他线程唤醒。
        pthread_mutex_lock(&glock);
        pthread_cond_wait(&gcond,&glock);
        --cnt;
        std::cout << name << "cnt  " << cnt << std::endl;
        pthread_mutex_unlock(&glock);
    }

    return nullptr;
}

int main()
{
    pthread_t t1 , t2;

    pthread_create(&t1,nullptr,Name,(void*)"Thread 1");
    pthread_create(&t2,nullptr,Name,(void*)"Thread 2");

    while(true)
    {
        // 唤醒一个进程。
        pthread_cond_signal(&gcond);
        // 唤醒全部进程。
        //pthread_cond_broadcast(&gcond);
        sleep(1);
    }

    pthread_join(t1,nullptr);
    pthread_join(t2,nullptr);

    return 0;
}

// 错误待查：unlock写lock了
// ******************************************************
// 按道理来讲两份代码思路都是一样的。
// #include <iostream>
// #include <string>
// #include <pthread.h>
// #include <unistd.h>

// int ticket = 1000;

// // 全局条件变量初始化。
// pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;

// pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

// void* Sell (void* argv)
// {
//     std::string name = static_cast<char*>(argv);

//     while(true)
//     {
//         pthread_mutex_lock(&glock);
//         pthread_cond_wait(&gcond,&glock);
//         std::cout << name << std::endl;
//         pthread_mutex_unlock(&glock);
//     }

//     return nullptr;
// }

// int main()
// {
//     // pthread_cond_t con;

//     // pthread_cond_init(&con,NULL);

//     pthread_t t1 , t2 , t3 , t4;

//     pthread_create(&t1,nullptr,Sell,(void*)"Thread 1");
//     pthread_create(&t2,nullptr,Sell,(void*)"Thread 2");

//     sleep(3); // 可有可无，这里确保两个线程已经在运行。

//     while(true)
//     {
//         // 唤醒一个线程。
//         //pthread_cond_signal(&cond);
//         // 唤醒多个线程。
//         pthread_cond_broadcast(&gcond);
//         sleep(1);
//     }

//     pthread_join(t1,nullptr);
//     pthread_join(t2,nullptr);

//     return 0;
// }